home *** CD-ROM | disk | FTP | other *** search
/ Games of Daze / Infomagic - Games of Daze (Summer 1995) (Disc 1 of 2).iso / x2ftp / msdos / libs / knowhow4 / ic_part.cpp < prev    next >
C/C++ Source or Header  |  1994-10-10  |  6KB  |  210 lines

  1. #include "ic_part.h"
  2.  
  3. #include <mem.h>
  4. #include "image_p.h"
  5. #include "output.h"
  6.  
  7. //////////////////////////
  8. void cut_image_horiz(imageP image, int height, int leave_up)
  9.     {
  10.     if(leave_up)
  11.     imageP(image)->ymax = height - 1;
  12.     else
  13.     {
  14.     int line_size = ((imageP(image)->xmax + 1 + 7) >> 3) << N_PLANE_SH;
  15.     memcpy(imageP(image)->data,
  16.            imageP(image)->data + line_size * height,
  17.            (imageP(image)->ymax + 1 - height) * line_size);
  18.     imageP(image)->ymax -= height;
  19.     }
  20.     }
  21. //////////////////////////
  22. void cut_image_vert(imageP image, int width, int leave_left)
  23.     {
  24.     int line_bytes_old = ((image->xmax + 1 + 7) >> 3);
  25.     if(leave_left)
  26.     {
  27.     int line_bytes_new = (width + 7) >> 3;
  28.     image->xmax = width - 1;
  29.  
  30.     int i, s, d;
  31.  
  32.     for(i = s = d = 0; i <= image->ymax; i++)
  33.         {
  34.         for(int plane = 0; plane < N_PLANES; plane++)
  35.         {
  36.         for(int j = 0; j < line_bytes_new; j++)
  37.             image->data[d++] = image->data[s + j];
  38.         s += line_bytes_old;
  39.         }
  40.         }
  41.     }
  42.     else
  43.     {
  44.     int bits_left = image->xmax - width + 1;
  45.     int i, s, d;
  46.     int line_bytes_new = line_bytes_old - ((width + 7) >> 3);
  47.     s = (width + 7) >> 3;
  48.     for(i = d = 0; i <= image->ymax; i++)
  49.         {
  50.         for(int plane = 0; plane < N_PLANES; plane++)
  51.         {
  52.         for(int j = 0; j < line_bytes_new; j++)
  53.             image->data[d++] = image->data[s + j];
  54.         s += line_bytes_old;
  55.         }
  56.         }
  57.     image->xmax = bits_left - 1;
  58.     }
  59.     }
  60. ////////////////////////////
  61. inline void image_cut(imageP image, imageP work, int x, int bplin, int sz)
  62.     {
  63.     unsigned char* dest = work->data;
  64.     unsigned char* src = image->data + (x >> 3);
  65.  
  66.     memcpy(dest, src, sz);                 // for 4 planes
  67.     memcpy(dest += sz, src += bplin, sz);
  68.     memcpy(dest += sz, src += bplin, sz);
  69.     memcpy(dest += sz, src += bplin, sz);
  70.     }
  71. ////////////////////////////
  72. void cut_image(imageP image, rect src, rect dest)
  73.     {
  74.     int leave_left = 0;
  75.     int leave_up = 0;
  76.     int height, width;
  77.  
  78.     if(src.origin.X == dest.origin.X)
  79.     {
  80.     leave_left = 1;
  81.     width = dest.width();
  82.     }
  83.     else
  84.     width = src.width() - dest.width();
  85.     if(src.origin.Y == dest.origin.Y)
  86.     {
  87.     leave_up = 1;
  88.     height = dest.height();
  89.     }
  90.     else
  91.     height = src.height() - dest.height();
  92.  
  93.     if(!(src.origin.Y == dest.origin.Y && src.corner.Y == dest.corner.Y))
  94.     cut_image_horiz(image, height, leave_up);
  95.     if(!(src.origin.X == dest.origin.X && src.corner.X == dest.corner.X))
  96.     cut_image_vert(image, width, leave_left);
  97.     }
  98. ///////////////////////////
  99. void put_image_correct(imageP image, rect src) // src in abs screen coord
  100.     {
  101.     struct viewporttype viewinfo;
  102.     getviewsettings(&viewinfo);
  103.  
  104.     setviewport(0, 0, getmaxx(), getmaxy(), 1);
  105.  
  106.     rect r(viewinfo.left, viewinfo.top, viewinfo.right, viewinfo.bottom);
  107.  
  108.     if(r.contains(src))
  109.     {
  110.     putimage(src.origin.X, src.origin.Y, image, COPY_PUT);
  111.     setviewport(viewinfo.left, viewinfo.top,
  112.             viewinfo.right, viewinfo.bottom, 1);
  113.     return;
  114.     }
  115.     if(!r.contains(src.origin) && !r.contains(src.corner) &&
  116.        !r.contains(loc(src.origin.X, src.corner.Y))       &&
  117.        !r.contains(loc(src.corner.X, src.corner.Y)))
  118.      {
  119.      setviewport(viewinfo.left, viewinfo.top,
  120.              viewinfo.right, viewinfo.bottom, 1);
  121.      return;
  122.      }
  123.     rect dest;
  124.     dest.origin.X = r.origin.X > src.origin.X ? r.origin.X : src.origin.X;
  125.     dest.origin.Y = r.origin.Y > src.origin.Y ? r.origin.Y : src.origin.Y;
  126.     dest.corner.X = r.corner.X < src.corner.X ? r.corner.X : src.corner.X;
  127.     dest.corner.Y = r.corner.Y < src.corner.Y ? r.corner.Y : src.corner.Y;
  128.  
  129.     cut_image(image, src, dest);
  130.     putimage(dest.origin.X, dest.origin.Y, image, COPY_PUT);
  131.  
  132.     setviewport(viewinfo.left, viewinfo.top,
  133.         viewinfo.right, viewinfo.bottom, 1);
  134.     }
  135. //////////////////////////
  136. void cut(imageP image, rect src)  // src - position of rectangle inside image
  137.     {
  138.     cut_image(image, rect(0, 0, image->xmax, image->ymax),
  139.     rect(src.origin, loc(image->xmax, image->ymax)));
  140.     src.corner.X -= src.origin.X;
  141.     src.corner.Y -= src.origin.Y + 1;
  142.     cut_image(image, rect(0, 0, image->xmax, image->ymax),
  143.     rect(0, 0, src.corner.X, src.corner.Y));
  144.     }
  145. ////////////////////////////
  146. void putimage(int x, int y, imageP image,    // for 25x80 cells screen, show
  147.           int* cells, imageP work,       // only cells, which are listed
  148.           int bplin, int mode)
  149.     {
  150.     if(cells == NULL)
  151.     ::putimage(x, y, image, mode);
  152.     else
  153.     {
  154.     int i = 0;   // Cells counter
  155.     rect r_out = textRect(rect(x, 0, x + image->xmax, 0));
  156.     int r_out_L = r_out.origin.X;
  157.     int r_out_R = r_out.corner.X;
  158.  
  159.     int num = 0;                        // Number of continuous cells.
  160.     int s_left;                         // First cell in visible raw
  161.     int raw = y / pScreenSet->cell_height;
  162.  
  163.     int bytes_per_cell = 1 << (pScreenSet->log2cell_width - 3);
  164.         int reserv = -5;
  165.     while(cells[i] != -1)
  166.         {
  167.         int top = cells[i] / 80;
  168.  
  169.         if(raw != top || cells[i] < 0)            // Skip this raw
  170.         {
  171.         i++; continue;
  172.         }
  173.         int left = cells[i] - top * 80;
  174.         if(!num)                   // Start in raw of cells
  175.         s_left = left;
  176.         if(left < r_out_R && left >= r_out_L
  177.            && (!num || (cells[i] == reserv + 1)))
  178.         {
  179.                 reserv = cells[i];
  180.  
  181.         if(!((y + 1) % pScreenSet->cell_height))
  182.             cells[i] = -2;
  183.         num++;
  184.                 }
  185.         else
  186.                 {
  187.             if(num)                        // end of visible raw
  188.             {
  189.             int r_left = screenXL(s_left);
  190.             int sz = bytes_per_cell * num;
  191.             work->xmax = (num << pScreenSet->log2cell_width) - 1;
  192.             image_cut(image, work, r_left - x, bplin, sz);
  193.             ::putimage(r_left, y, work, mode);
  194.             num = 0;
  195.                     i--;
  196.             }
  197.                 }
  198.         i++;
  199.         }
  200.     if(cells[i] == -1 && num)
  201.         {
  202.         int r_left = screenXL(s_left);
  203.         int sz = bytes_per_cell * num;
  204.         work->xmax = (num << pScreenSet->log2cell_width) - 1;
  205.         image_cut(image, work, r_left - x, bplin, sz);
  206.         ::putimage(r_left, y, work, mode);
  207.         }
  208.     }
  209.     }
  210.